/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:        http://wiki.pic24.ru/doku.php/en/osa/ref/intro                                  *
 *              http://picosa.narod.ru                                                          *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:       osa_csem.h                                                                      *
 *                                                                                              *
 *  Compilers:  HT-PICC STD                                                                     *
 *              HT-PICC18 STD                                                                   *
 *              Microchip C18                                                                   *
 *              Microchip C30                                                                   *
 *                                                                                              *
 *  Programmer: Timofeev Victor                                                                 *
 *              osa@pic24.ru, testerplus@mail.ru                                                *
 *                                                                                              *
 *  Definition: Services for work with counting semaphores                                      *
 *                                                                                              *
 ************************************************************************************************
 */


/************************************************************************************************
 *                                                                                              *
 *                            C O U N T I N G   S E M A P H O R E S                             *
 *                                                                                              *
 ************************************************************************************************/




#ifdef OS_ENABLE_CSEM


// These services are used in countsem functions (see OSA.C)

#if defined(OS_ENABLE_INT_CSEM) && (OS_CSEM_SIZE > 1)
    #define __OS_CSEM_DI()       {_OS_temp = OS_DI();}
    #define __OS_CSEM_RI()       {OS_RI(_OS_temp);}
#else
    #define __OS_CSEM_DI()
    #define __OS_CSEM_RI()
#endif




//------------------------------------------------------------------------------
// Increase counting semaphore's value by 1
#define OS_Csem_Signal(countsem)                                        \
    {                                                                   \
        _OS_Csem_Signal(&(countsem));                                   \
    }

//------------------------------------------------------------------------------
// Set counting semaphore's value to given value
#define OS_Csem_SetValue(countsem,value)                                \
    {                                                                   \
        __OS_CSEM_DI();                                                 \
        countsem = value;                                               \
        __OS_CSEM_RI();                                                 \
    }

//------------------------------------------------------------------------------
// Accepting counting semaphore. Decrease it's value by 1.
#define OS_Csem_Accept(countsem)                                        \
    {                                                                   \
        __OS_CSEM_DI();                                                 \
        countsem--;                                                     \
        __OS_CSEM_RI();                                                 \
    }

//------------------------------------------------------------------------------
// Set counting semaphore's value to 1.
#define OS_Csem_Set(countsem)    OS_Csem_SetValue(countsem, 1)
#define OS_Csem_Reset(countsem)  OS_Csem_SetValue(countsem, 0)
#define OS_Csem_Create(countsem) OS_Csem_SetValue(countsem, 0)


//------------------------------------------------------------------------------
#if (OS_CSEM_SIZE == 1) || (!defined(OS_ENABLE_INT_CSEM))

    // Check counting semaphore for non zero value
    #define OS_Csem_Check(countsem)                      (countsem)

#else

    // Check counting semaphore for non zero value
    #define OS_Csem_Check(countsem)      _OS_Csem_Check(&(countsem))

#endif
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
#ifdef OS_ENABLE_INT_CSEM

    extern void _OS_Csem_Signal_I (OST_CSEM*);

    // Set counting semaphore's value to given value
    #define OS_Csem_SetValue_I(countsem,value)          countsem = value

    // Set counting semaphore's value to 1
    #define OS_Csem_Set_I(countsem)                     OS_Csem_SetValue_I(countsem, 1)

    // Clear counting semaphore
    #define OS_Csem_Reset_I(countsem)                   countsem = 0

    // Check counting semaphore for non zero value
    #define OS_Csem_Check_I(countsem)                   (countsem)

    // Accept counting semaphore. Decrease it's value by 1
    #define OS_Csem_Accept_I(countsem)                  countsem--

    // Increase counting semaphore's value by 1
    #define OS_Csem_Signal_I(countsem)                  _OS_Csem_Signal_I(&countsem)

#endif


//------------------------------------------------------------------------------
// Wait counting semaphore
#define OS_Csem_Wait(countsem)                                          \
    {                                                                   \
        _OS_WAIT_EVENT(OS_Csem_Check(countsem));                        \
        OS_Csem_Accept(countsem);                                       \
    }

//------------------------------------------------------------------------------
// Wait counting semaphore. Exit if timeout expired.
#define OS_Csem_Wait_TO(countsem, timeout)                              \
    {                                                                   \
        _OS_WAIT_EVENT_TIMEOUT(OS_Csem_Check(countsem), timeout);       \
        if (!OS_IsTimeout()) {                                          \
            OS_Csem_Accept(countsem);                                   \
        }                                                               \
    }


//------------------------------------------------------------------------------
#endif  // OS_ENABLE_CSEM















